﻿
namespace CoProjectDF.Views.Login
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using CoProjectDF.Models.Login;
    using CoProjectModel;
    using IdeaBlade.Application.Framework.Core.Authentication;
    using IdeaBlade.Application.Framework.Core.Persistence;
    using IdeaBlade.EntityModel;

    /// <summary>
    /// View model for the RegistrationForm.
    /// </summary>
    public partial class RegistrationViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private RegisterUserRepository rr;

        public RegistrationViewModel()
        {
            if (DesignerProperties.IsInDesignTool)
            {
                RegistrationData = new RegistrationData();
            }
            else
            {
                AuthenticationService = Caliburn.Micro.IoC.Get<IAuthenticationService>();
                EntityManagerProvider = Caliburn.Micro.IoC.Get<IEntityManagerProvider<CoProjectModel.CoProjectEntities>>();
                rr = new RegisterUserRepository();

                //RegistrationData = AuthenticationManager.Current.CreateEntity<RegistrationData>();
                RegistrationData = new RegistrationData();
                RegistrationData.VerifierEngine = EntityManagerProvider.Manager.VerifierEngine;
            }
        }

        /// <summary>
        /// Current registration data.
        /// </summary>
        public RegistrationData RegistrationData { get; private set; }

        /// <summary>
        /// True if the registration request is underway.
        /// </summary>
        public bool IsRegistering
        {
            get { return CurrentOperation != null && !CurrentOperation.IsCompleted; }
        }

        /// <summary>
        /// Gets a value indicating whether the user can presently register.
        /// </summary>
        public bool CanRegister
        {
            get { return !IsRegistering; }
        }

        /// <summary>
        /// True if the operation can be canceled.
        /// </summary>
        public bool CanCancel
        {
            get { return CurrentOperation == null || CurrentOperation.IsCompleted; }
        }

        /// <summary>
        /// Register the user.
        /// </summary>
        /// <param name="callback"></param>
        public void RegisterUser(Action<BaseOperation> callback)
        {
            if (!CanRegister) return;

            //CurrentOperation = AuthenticationManager.Current.RegisterUser(RegistrationData, callback: callback);
            CurrentOperation = rr.RegisterUser(RegistrationData, callback: callback);
            CurrentOperation.Completed += (s, e) =>
            {
                UpdateState();
                AuthenticationService.LogoutAsync();
            };
        }

        /// <summary>
        /// Cancel registration processing.
        /// </summary>
        public void Cancel()
        {
            if (CanCancel)
            {
                UpdateState();
            }
        }

        /// <summary>
        /// Sets a function that returns the password.
        /// </summary>
        internal void SetPasswordAccessor(Func<string> accessor)
        {
            RegistrationData.PasswordAccessor = accessor;
        }

        /// <summary>
        /// Sets a function that returns the password confirmation.
        /// </summary>
        internal void SetPasswordConfirmationAccessor(Func<string> accessor)
        {
            RegistrationData.PasswordConfirmationAccessor = accessor;
        }

        /// <summary>
        /// Retrieves localized security questions.
        /// </summary>
        internal IEnumerable<string> SecurityQuestions
        {
            get
            {
                // Use reflection to grab all the localized security questions
                return from propertyInfo in typeof(SecurityQuestions).GetProperties()
                       where propertyInfo.PropertyType.Equals(typeof(string))
                       select (string)propertyInfo.GetValue(null, null);
            }
        }

        /// <summary>
        /// Gets or sets the current registration operation.
        /// </summary>
        private BaseOperation CurrentOperation { get; set; }

        private void UpdateState()
        {
            RaisePropertyChanged("IsRegistering");
            RaisePropertyChanged("CanRegister");
            RaisePropertyChanged("CanCancel");
        }

        protected virtual void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        /// <summary>
        /// Gets or Sets the AuthenticationService from the IoC container.
        /// </summary>
        private IAuthenticationService AuthenticationService { get; set; }

        /// <summary>
        /// Gets or Sets the EntityManagerProvider from the IoC container.
        /// </summary>
        private IEntityManagerProvider<CoProjectModel.CoProjectEntities> EntityManagerProvider { get; set; }
    }
}
